<template>
  <div>
    <!-- 子组件模板 -->
    <h3>子组件</h3>
    <div>
      <h3>{{ props.title }}</h3>
      <p>{{ props.count }}</p>
      <p>{{ props.charName }}</p>
      <p>{{ props.char.name }}</p>
      <button @click="props.handleClick(detailId)">向父组件传递数据</button>
    </div>
  </div>
</template>

<script lang="ts" setup>
/**
 * Props 详解
 * 
 * 1. 概念：
 *    Props 是 Vue 中父组件向子组件传递数据的一种方式。
 *    它是单向数据流，只能从父组件流向子组件，子组件不能直接修改 props。
 * 
 * 2. 基本使用：
 *    - 父组件通过属性传递数据
 *    - 子组件通过 defineProps 声明接收的 props
 * 
 * 3. Props 的声明方式：
 *    3.1 简单数组语法：
 *        const props = defineProps(['title', 'content'])
 * 
 *    3.2 对象语法（推荐，可以指定类型）：
 *        const props = defineProps({
 *          title: String,
 *          content: String,
 *          count: Number,
 *          isActive: Boolean,
 *          items: Array,
 *          user: Object,
 *          onClick: Function
 *        })
 * 
 *    3.3 TypeScript 类型声明（在 <script setup> 中最推荐）：
 *        const props = defineProps<{
 *          title: string
 *          content?: string // 可选 prop
 *          count: number
 *          isActive: boolean
 *          items: string[]
 *          user: { id: number; name: string }
 *          onClick: (id: number) => void
 *        }>()
 * 
 *    3.4 带默认值的 TypeScript 声明：
 *        const props = withDefaults(defineProps<{
 *          title: string
 *          content?: string
 *          count?: number
 *        }>(), {
 *          content: '默认内容',
 *          count: 0
 *        })
 * 
 * 4. Props 验证：
 *    const props = defineProps({
 *      // 基础类型检查
 *      title: String,
 *      // 多种类型
 *      id: [String, Number],
 *      // 必填项
 *      content: {
 *        type: String,
 *        required: true
 *      },
 *      // 带默认值
 *      count: {
 *        type: Number,
 *        default: 0
 *      },
 *      // 对象默认值
 *      user: {
 *        type: Object,
 *        default: () => ({ name: '默认用户' })
 *      },
 *      // 自定义验证函数
 *      score: {
 *        type: Number,
 *        validator: (value) => value >= 0 && value <= 100
 *      }
 *    })
 * 
 * 5. Props 的应用场景：
 *    5.1 组件复用：通过不同的 props 创建功能相似但展示不同的组件实例
 *    5.2 UI 组件库：如按钮组件接收颜色、大小、文本等 props
 *    5.3 数据展示：如列表组件接收数据项和配置选项
 *    5.4 配置组件行为：通过 props 控制组件的功能和表现
 *    5.5 组件通信：作为父子组件之间的基本通信方式
 * 
 * 6. Props 的注意事项：
 *    6.1 单向数据流：子组件不应该修改 props，应该通过事件通知父组件修改
 *    6.2 对象和数组是引用类型：即使不能直接替换 props，但可以修改其内部属性（应避免）
 *    6.3 Prop 命名：在 HTML 中使用 kebab-case (如 my-prop)，在组件中使用 camelCase (如 myProp)
 *    6.4 Boolean 类型的 props：仅写属性名而不传值时，值为 true
 * 
 * 7. 处理 Props 变化：
 *    7.1 使用 watch 监听 props 变化：
 *        watch(() => props.count, (newValue, oldValue) => {
 *          // 处理 props 变化
 *        })
 *    
 *    7.2 使用计算属性基于 props 派生值：
 *        const formattedTitle = computed(() => {
 *          return props.title.toUpperCase()
 *        })
 * 
 * 8. 非 Prop 的 Attribute：
 *    - 没有被声明为 props 的属性会自动添加到组件的根元素上
 *    - 可以通过 inheritAttrs: false 选项或 v-bind="$attrs" 自定义处理
 */
import { defineProps,ref } from 'vue'
// 这里声明接收的 props
const props = defineProps(['title', 'count','charName','char','handleClick'])
console.log(props)

const detailId = ref('10001');
</script>

<style scoped>
/* 子组件样式 */
div {
  background: linear-gradient(to right, #f6d365, #fda085);
  border-radius: 12px;
  padding: 20px;
  margin: 15px 0;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

div:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

h3 {
  color: #ffffff;
  font-size: 22px;
  margin-bottom: 15px;
  text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  font-weight: 500;
  letter-spacing: 1px;
}
</style>